<!--
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
-->

<!--
  Simple page for testing gadgets.rpc performance.
  Allows you to add a simulated "gadget" (in this case just a static
  HTML page which loads gadgets.rpc also), and pass some
  specified number of random messages of specified size to
  and from it.

  To use, start up two instances of
  the Shindig Gadgets Server on two separate ports to test
  "real" cross-domain communication, since port is factored
  into the same-domain policy enforced by browsers. One
  server will be used for the container, the other for the gadget.

  If your container on localhost:8080 with gadget on localhost:8081,
  then to load the test load the following in your browser:
  http://localhost:8080/gadgets/files/container/rpctest_container.html?localhost:8081

  This test container/gadget pair is configurable via two other options:
  * &gadgetdeferred=1 - tests early-message queueing from container to
    gadget, by preventing attachment of gadget until a button is pressed.
  * &uselegacy=1 - tests legacy IFPC functionality.
  * &uabackward=1 - tests "incorrect" rpc.js setup in container:
    gadgets.rpc.setAuthToken(...) called before, not after, gadget frame exists.

  These options may be provided in any combination.
-->
<html>
  <head>
    <title>gadgets.rpc Performance Tests: Container</title>
    <script>
      // Configurable test harness options.
      var gadgethost = 'http://' + window.location.search.substring(1).split('&')[0];
      var gadgetdeferred = window.location.search.indexOf('&gadgetdeferred=1') !== -1;
      var uselegacy = window.location.search.indexOf('&uselegacy=1') !== -1;
      var uabackward = window.location.search.indexOf('&uabackward=1') !== -1;

      // Useful per-page variables.
      var gadgeturl = gadgethost + '/gadgets/files/container/rpctest_gadget.xml';
      var cachebust = 'cachebust=' + Math.random();
      var gadgetrenderingurl = gadgethost + '/gadgets/ifr?url=' + gadgeturl + '&libs=rpc&parent=' + window.location.protocol + '//' + window.location.host + '&debug=1&' + cachebust;
      var gadgetrelay = gadgethost + '/gadgets/files/container/rpc_relay.uncompressed.html';

      // Set up faux gadgets.config(...)
      var gadgets = {};
      gadgets.config = {
        register: function(rpc, requiredConfig, callback) {
          // rpc === "rpc", requiredConfig is ignored here.
          // Just call the callback (function init(...) in rpc.js)
          // with a dummy config object.
          callback({ rpc: { parentRelayUrl: "", uselegacyProtocol: uselegacy } });
        }
      };

      // Include rpc.js. Append random cache-busting param to ensure caching doesn't occur.
      document.write('<scr' + 'ipt language="JavaScript" type="text/javascript" src="' +
                     '/gadgets/js/rpc.js?c=1&debug=1&' + cachebust + '"></scr' + 'ipt>');

      // Include rpctest_perf.js JS test helper, also with cachebusting.
      document.write('<scr' + 'ipt language="JavaScript" type="text/javascript" src="' +
                     '/gadgets/files/container/rpctest_perf.js?' + cachebust + '"></scr' + 'ipt>');
    </script>
    <!-- need a script break to allow rpc.js to load before calling referenced methods -->
    <script>
      // gadgets.rpc "service" that receives a message sent before body onload.
      function handleInitialGadgetMessage(message) {
        var status = document.getElementById('initconsole');
        status.innerHTML = 'gadget says: ' + message;
      }
      gadgets.rpc.register('initial_gadget_message', handleInitialGadgetMessage);

      function handleGadgetServicePing() {
        var childping = document.getElementById('childping');
        var pingval = childping.innerHTML;
        pingval++;
        childping.innerHTML = pingval;
      }
      gadgets.rpc.register('gadget_service_ping', handleGadgetServicePing);
    
      function appendGadget() {
        var secret = Math.round(Math.random() * 10000000);
        var renderUrl = gadgetrenderingurl + '#rpctoken=' + secret;
        var container = document.getElementById("container");

        // Rendering about:blank first seems to fix bfcache issue (mismatched rpc tokens)
        var iframeHtml = "<iframe id='gadget' name='gadget' height=400 width=800 src='about:blank'></iframe>";
        if (uabackward) {
          // incorrect but likely widely used
          gadgets.rpc.setRelayUrl('gadget', gadgetrelay);
          gadgets.rpc.setAuthToken('gadget', secret);
          container.innerHTML = iframeHtml;
          document.getElementById('gadget').src = renderUrl;
        } else {
          // "correct" way.
          container.innerHTML = iframeHtml;
          document.getElementById('gadget').src = renderUrl;
          gadgets.rpc.setupReceiver('gadget'); // use the new init API, which parses out all needed variables.
        }
      }

      function initTestContainer() {
        if (!gadgetdeferred) {
          appendGadget();
        } else {
          document.getElementById('showgadget').style.display = '';
        }

        document.getElementById('relaymethod').innerHTML = gadgets.rpc.getRelayChannel();

        // Method called from rpctest_perf.js
        initPerfTest();
      };
    </script>
  </head>
  <body style="background-color: #cccccc" onload="initTestContainer();">
    <div>gadgets.rpc Performance: Container Page (method: <span id="relaymethod"></span>)</div><hr/>
    <div>Initial gadget render console: <span id="initconsole">Gadget hasn't commented yet.</span></div>
    <div>Child gadget ping count: <span id="childping">0</span></div><hr/>
    <div>Test<br/>
      <ul>
        <li>Number of messages to send:
          <select name="num_msgs" id="num_msgs">
            <option value="1" selected>1</option>
            <option value="10">10</option>
            <option value="100">100</option>
            <option value="1000">1000</option>
          </select>
        </li>
        <li>Message size:
          <select name="msg_size" id="msg_size">
            <option value="10">10 B</option>
            <option value="100">100 B</option>
            <option value="1024" selected>1 kB</option>
            <option value="10240">10 kB</option>
            <option value="102400">100 kB</option>
            <option value="1048576">1 MB</option>
          </select>
        </li>
        <li>
          <input type="button" value="Start The Test!" onclick="runPerfTest('gadget');" />
        </li>
      </ul>
    </div>
    <div id="test_running" style="display:none;">
      Running test...
    </div>
    <div id="results" style="display:none;">
      Results: Gadget-to-Container<br/>
      Messages: <span id="results_num_received"></span>, Bytes: <span id="results_bytes_received"></span> <span id="in_or_out"></span><br/>
      Time elapsed for test run: <span id="results_time_used"></span><br/>
      Messages/second: <span id="results_msgs_per_sec"></span><br/>
      Bytes/second: <span id="results_bytes_per_sec"></span>
    </div>
    <hr/>
    <div>Callback<br/>
      <ul>
        <li>Input: <input type="text" value="test-value" size="20" id="echo_test_input"/> <input type="button" value="Sync Callback Test" onclick="runCallbackTest('gadget',true);"/> <input type="button" value="Async Callback Test" onclick="runCallbackTest('gadget',false);"/></li>
        <li>Result: <span id="echo_test_result"></span></li>
      </ul>
    </div>
    <hr/>
    <div>Gadget: <span id="showgadget" style="display:none"><input type="button" onclick="appendGadget(); this.style.display='none';" value="Append Gadget Now (for delayed load testing)"/></span></div>
    <div id="container"></div>
  </body>
</html>
